<script setup>
import UserInfo from '@/components/userInfo.vue'
import { reactive, ref ,nextTick, watch, computed} from "vue";
import { updateUserInfoApi} from '@/api/admin/user'
import { ElMessage, ElMessageBox } from "element-plus";
import updataUserInfo from '@/components/admin/updataUserInfo.vue';
import {useRouter,useRoute } from 'vue-router'
import {postFileApi} from '@/api/file'
const router = useRouter()
const route = useRoute()
import {addRoleApi,delRoleApi,selectRoleApi,updateRoleApi,updateUserRoleApi} from '@/api/admin/role'
import { useUserStore } from '@/stores/user';
const userStore = useUserStore()
const loginUser = ref(userStore.userInfo)
//获取所有对应角色下的用户
const userList = reactive(new Map)
const pageInfo = ref({})
const roleList = reactive([])
//第一次加载界面 默认展示所有用户
getAllUser(0)
async function getAllUser(page){
  try{
    const resp = await selectRoleApi(page) 
    if(resp.data.code === 200){
      pageInfo.value = resp.data.data.page
      const Role = resp.data.data.content
      //清空旧数据
      if(page === 0){
        roleList.length = 0
        userList.clear()
      }
      if(Role.length !== 0){
        Role.forEach(Role =>{roleList.push(Role)})
        Role.forEach((role,index) =>{
          role.users.forEach((user,index)=>{
            userList.set(user.id,user)
          })
        })
      }
    }
  }catch(e){
    console.log(e)
  }
}
//重新设置某个标签下的用户
const updateAllUser =async(pageIndex)=>{
  if(value.value===''){
    getAllUser(0)
  }else{
    try{
      const resp = await selectRoleApi(pageIndex)
      const Role = resp.data.data.content

      //清空旧数据
      roleList.length = 0
      userList.clear()

      Role.forEach(Role =>{roleList.push(Role)})
      Role.forEach((role,index) =>{
        if(role.id === value.value){
          const users = role.users
          users.forEach((user,index)=>{
            userList.set(user.id,user)
          })
        }
      })

    }catch(e){
      ElMessage.error('重新获取用户列表异常')
      console.log(e)
    }
  }
}
const value = ref('')//记录当前role的id

//处理下拉框的选择
const handleSelect = async (command) => {
  value.value = command
  return
}
watch(value,async (newValue)=>{
  roleList.forEach(Role =>{
    if(Role.id === newValue){
      userList.clear()
      Role.users.forEach(user =>{
        userList.set(user.id,user)
      })
    }
  })
})

//出现用户信息修改框
const showUpdataBox = ref(false)
const showUserInfo = reactive({})
const onUpdate = (userInfo)=>{
  showUpdataBox.value = true
  showUserInfo.value = userInfo
}
const onConfirm =async (userInfo)=>{
  //参数校验
  if(userInfo.username.length > 0 && (userInfo.username.length < 6 || userInfo.username.length > 20)){
    ElMessage.warning('用户名长度在6~20之间')
    return
  }
  if(userInfo.phone.length > 0 &&userInfo.phone.length !== 11){
    ElMessage.warning('请输入正确手机号')
    return
  }
  const inputEmail = userInfo.email
  const reg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
  if(!reg.test(inputEmail)){
    ElMessage.warning('邮箱格式不正确，请重新输入')
    return
  }
  if('password' in userInfo){
    if(userInfo.password !== '' ){
      if(userInfo.password.length < 6 || userInfo.password.length > 16){
        ElMessage.warning('密码长度在6~16之间')
        return
      }
    } 
  }else{
    userInfo.password = ''
  }
  try{
    const resp = await updateUserInfoApi(userInfo)
    if(resp.data.code === 200){
      showUpdataBox.value = false
      //重新获取用户列表信息
      getAllUser(0)
      //判断被修改的用户是否为登录用户 如果是就更新pinia 本地存储
      if(loginUser.value.id === userInfo.id){
        userStore.setUserInfo(resp.data.data)
      }
      ElMessage.success('修改成功')
      
    }
  }catch(e){
    console.log(e)
  }
}
//修改user头像
const setHeadImg = async (file,userInfo)=>{
    try{
       const reqData = userInfo
       const response = await postFileApi(file)
       reqData.avatar = response.data.data[0]
       const resp = await updateUserInfoApi(reqData)
    }catch(e){
        console.log(e)
    }
}
//出现角色修改框
const showRoleBox = ref(false)
const userId = ref(null)
const onSetRole = (id)=>{
  showRoleBox.value = true
  userId.value = id
}
//角色类型修改
const roleForm = ref([{
  type:''
}])
//----修改标签-----------------
const onSubmit = async ()=>{
  const addRoleIdArr =  roleForm.value
  if(typeof addRoleIdArr.type === 'undefined'){
    ElMessage.warning('请至少选择一个标签！')
    return
  }
  //判断被修改的用户是否为登录用户 并且选中角色没有admin 给出提示
  const adminId = ref()
  const includeAdmin = ref(false)
  if(userId.value === loginUser.value.id){
    roleList.forEach((Role)=>{
      //找到admin标签对应的id
      if(Role.name === 'admin'){
        adminId.value = Role.id
        if(addRoleIdArr.type.includes(Role.id)){
          includeAdmin.value = true
        }
      }
    })
    //被选中的标签不包含管理员
    if(!includeAdmin.value){
      ElMessageBox.confirm(
        '您将失去管理员身份，确认还要继续吗？',
        '警告',
        {
          confirmButtonText:'确认',
          cancelButtonText:'取消',
          type:'warning'
        }
      ).then(async()=>{
        //1.添加选中的角色
        try{
          const addRole = addRoleIdArr.type.map(id=>{
            return updateUserRoleApi(userId.value,id,'add')
          })
          await Promise.all(addRole)
        }catch(e){
          console.log(e)
          return
        }
        //2.移除未被选中的角色（除管理员角色）
        roleList.forEach(async(Role)=>{
          let beSelect = false
          if(addRoleIdArr.type.includes(Role.id)){
            beSelect = true
          }
          if(!beSelect && Role.id !== adminId.value){
            try{
               await updateUserRoleApi(userId.value,Role.id,"remove")
            }catch(e){
              console.log(e)
              return
            }
          }
        })
        //3.移除管理员角色
        try{
          await updateUserRoleApi(userId.value,adminId.value,"remove")
          //跳转达到登录界面 重新进入系统
          roleForm.value=[]
          showRoleBox.value = false
          router.push('/login')
          ElMessage.success('修改身份信息成功，请重新登录')
        }catch(e){
          console.log(e)
          return
        }
      })
    }else{
      //被选中的标签包含管理员
      //1.添加选中的角色
      try{
          const addRole = addRoleIdArr.type.map(id=>{
            return updateUserRoleApi(userId.value,id,'add')
          })
          await Promise.all(addRole)
        }catch(e){
          console.log(e)
          return
        }
      //2.移除未选中的角色
      roleList.forEach(async(Role)=>{
        let beSelect = false
        if(addRoleIdArr.type.includes(Role.id)){
          beSelect = true
        }
        if(!beSelect){
          try{
             await updateUserRoleApi(userId.value,Role.id,"remove")
          }catch(e){
            console.log(e)
            return
          }
        }
      })
      updateAllUser(0)
      showRoleBox.value = false
      roleForm.value=[]
      ElMessage.success('修改成功') 
    }
  }else{
    //移除所有角色
    try{
      const removeRole = roleList.map(role=>{
        return updateUserRoleApi(userId.value,role.id,"remove")
      })
      const resp = await Promise.all(removeRole)
    }catch(e){
      ElMessage.error('移除用户角色异常')
      console.log(e)
      return
    }
    //添加选中的角色
    try{
      const addRole = addRoleIdArr.type.map(id=>{
        return updateUserRoleApi(userId.value,id,'add')
      })
      const resp = await Promise.all(addRole)
      updateAllUser(0)
      showRoleBox.value = false
      roleForm.value=[]
      ElMessage.success('修改成功')  
    }catch(e){
      ElMessage.error('添加用户角色异常')
      console.log(e)
      return
    }
  }
}
 //取消
 const onCancle = ()=>{
  showRoleBox.value = false
 }
  //取消
  const cancle = ()=>{
  showUpdataBox.value = false
 }
 const listType = ref('')
//获取下一页数据
const getMoreUser = async ()=>{
   if(pageInfo.value.totalPages === 1 
   || pageInfo.value.number >= pageInfo.value.totalPages){
    return
   }
   getAllUser(pageInfo.value.number+1)
}
</script>
<template>
  <div class="all-userInfo-box">
    <!-- 树形选择 -->
    <el-select
    v-model="listType"
    size="large"
    :change="handleSelect(listType)"
    placeholder="所有用户"
    style="width: 120px">
      <el-option
      v-for="role in roleList" :key="role.id"
      :label="role.name"
      :value="role.id"/>
    </el-select>
    <!-- 修改个人信息弹出框 -->
    <el-dialog
    v-model="showUpdataBox">
      <updataUserInfo
      :userInfo="showUserInfo"
      @updateUser="onConfirm"
      @cancle="cancle" 
      ></updataUserInfo>
    </el-dialog>
    <!-- 修改身份的弹出框 -->
    <el-dialog
      title="请选择标签："
      v-model="showRoleBox">
        <el-form>
          <el-form-item >
            <el-checkbox-group 
            v-model="roleForm.type">
              <el-checkbox 
              v-for="role in roleList" :key="role.id"
              :label="role.name"
              :value="role.id">
              </el-checkbox>
            </el-checkbox-group>
          </el-form-item>
          <el-foem-item>
            <el-button type="primary" @click="onSubmit">确定</el-button>
            <el-button
            @click="onCancle"
            >取消</el-button>
          </el-foem-item>
        </el-form>
    </el-dialog>
    <ul 
    :infinite-scroll-distance="20"
    v-infinite-scroll="getMoreUser"
    style="overflow: auto"
    class="userList">
      <li 
      v-for="([userId, userInfo],) in userList" :key="userId"
      class="row">
        <UserInfo 
        class="user"
        :shouUpload="false"
        @setHeadImg="setHeadImg"
        :userInfo="userInfo">
        </UserInfo>
        <div class="buttons">
          <el-button
          class="button"
          @click="onUpdate(userInfo)"
          >修改信息</el-button>
          <el-button
          class="button"
          @click="onSetRole(userInfo.id)"
          >修改标签</el-button>
        </div>
      </li>
    </ul>
  </div>
</template>

<style lang="scss" scoped>
.all-userInfo-box{
  width: 100%;
  height: 100%;
  .userList{
    height: 76vh;
    width: auto;
    overflow: scroll;
     .row{
      border-radius: 10px;
      list-style: none;
      background-color: aliceblue;
      margin: 20px;
      .user{

      }
      .buttons{
        .button{
          border-radius: 10px;
          margin: 5px;
        }
        display: flex;
        justify-content: end;
        align-items: center;
      }
    }
  }
}
::-webkit-scrollbar{
  display: none;
}
</style>